﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BookingHotel.Collezioni;
using BookingHotel.ClasseDiDominio;

namespace BookingHotel.ManagerHotel
{
    class HotelManager
    {

        private Hotel _hotel = new Hotel();
        private RoomsCollection _allRooms = new RoomsCollection();
        private PeriodsCollection _allPeriods = new PeriodsCollection();
        private BookingCollection _allBooking = new BookingCollection();
        private ClientsCollection _allClients = new ClientsCollection();

        public void SetHotelName(String name)
        {
            _hotel.Name = name;
        }
        
        public void SetHotelLocality(String locality)
        {
            _hotel.Locality = locality;
        }

        public void AddPeriod(DateTime startPeriod,DateTime endPeriod, decimal coefficent) 
        {
            _allPeriods.AddPeriod(startPeriod, endPeriod, coefficent);
        }

        public List<Period> getAllPeriodsInARange(DateTime starPeriod, DateTime endPeriod)
        {
            return  _allPeriods.GetPeriodsByDate( starPeriod, endPeriod);
        }

        public List<Period> GetAllPeriods()
        {
            return _allPeriods.PeriodCollection;
        }

        public void PrintInConsolleAllRooms()
        {
            Console.Write(_allRooms.ToString());
        }

        public void PrintInConsolleAllPeriods()
        {
            Console.Write(_allPeriods.ToString());
        }

        public void PrintInConsolleAllBooking()
        {
            Console.Write(_allBooking.ToString());
        }

        public void PrintInConsolleAllClients()
        {
            Console.Write(_allClients.ToString());
        }

        internal void AddRoom(string type, int capacity, decimal price, int quantity)
        {
            _allRooms.AddRoom(type, capacity, price, quantity);
        }

        internal int GetFreeRoomOfThisType(string typeRoom, DateTime startPeriod, DateTime endPeriod)
        {
            int numberOfRooms = _allRooms.GetQuantityOfThisTypeRoom(typeRoom);
            int occupiedRooms = _allBooking.GetOccupiedRoom(typeRoom, startPeriod, endPeriod);
            return numberOfRooms - occupiedRooms;
        }

        internal string GetLocality(string _nameLocality)
        {
            _hotel.Locality = _nameLocality;
            return "Località: " + _hotel.Locality;
        }

        internal Client GetDataClient(int _idClient)
        {
            return _allClients.GetClientById(_idClient);
        }

        public decimal PriceBooking(DateTime startBooking, DateTime endBooking, string TypeRoom, int RoomId)
        {
            int numberDays = Convert.ToInt32(endBooking - startBooking);
            SameRoom roomBooked = _allRooms.GetRoomById(RoomId);
            List<Period> vacancy = _allPeriods.GetPeriodsByDate(startBooking, endBooking);
                                                                                                                                                        
            foreach (var vac in vacancy)
            {
                if (vac.Coefficient < 1)
                    return (roomBooked.Price) * numberDays;
                else
                    if (vac.Coefficient > 1)
                        return (roomBooked.Price) * numberDays;
                    else
                        return (roomBooked.Price) * numberDays;
            }
        }

        internal void ControlMatchBetweenNumberRoomsAndNumberClients(string typeOfRoom, int numberPossibleFreeRoom, int numberPersons, DateTime startBooking, DateTime endBooking)
        {
            int capacityOfSelectedRoom = _allRooms.GetQuantityOfThisTypeRoom(typeOfRoom);
            int totCapacity = capacityOfSelectedRoom * numberPossibleFreeRoom;
            if ((totCapacity) <= numberPersons)
            {
                Console.WriteLine("Sono disponibili {0} camere {1} nel periodo scelto. Aggiungo la prenotazione?", numberPossibleFreeRoom, typeOfRoom);
                string answer = Console.ReadLine();
                if (answer == "sì")
                {
                    //Inserire dati cliente
                    string[] divider = {" "};
                    string dataClient = Console.ReadLine();
                    string[] data = dataClient.Split(divider, StringSplitOptions.RemoveEmptyEntries);

                    Client newClient = _allClients.AddClient(data[0], data[1], data[2]);
                    decimal price = _allRooms.GetPriceOfThisRoom(typeOfRoom);
                    //Aggiungere prenotazione
                    _allBooking.AddPrenotations(newClient, typeOfRoom, numberPossibleFreeRoom, price, startBooking, endBooking, newClient.Id);
                }
                else
                    Console.WriteLine("Arrivederci e grazie.");
            }
            else
            {
                int numberPersonWithoutRoom = totCapacity % numberPersons;
                //Cambiare tipo di stanza con quello rimanente dei tre, cercare disponibilità e rimettere a posto
                //il metodo addPrenotation in modo che possa contenere più tipi di stanze
                
                //Richiamata al metodo ControlMatchBetwwnnNumberRoomsAndNumberClients per terminare la ricerca della disponibilità stanza
                ControlMatchBetweenNumberRoomsAndNumberClients(typeOfRoom, numberPossibleFreeRoom, numberPersonWithoutRoom, startBooking, endBooking);
            }
        }

        internal void FindRoom(DateTime startBooking, DateTime endBooking, int numberPersons, string typeRoom)
        {
            int numberPossibleFreeRoom = GetFreeRoomOfThisType(typeRoom, startBooking, endBooking);
            string typeOfRoom = "";
            if (numberPossibleFreeRoom == 0)
            {
                Console.WriteLine("La stanza {0} da lei richiesta non è disponibile. Cerco tra le altre stanze?", typeRoom);
                string answer = Console.ReadLine();
                if (answer == "sì")
                {
                    if ((typeOfRoom == "singola" && typeOfRoom != typeRoom) || (typeOfRoom == "doppia" && typeOfRoom != typeRoom) || (typeOfRoom == "tripla" && typeOfRoom != typeRoom))
                    {
                        numberPossibleFreeRoom = GetFreeRoomOfThisType(typeOfRoom, startBooking, endBooking);
                        if (numberPossibleFreeRoom != 0)
                        {
                            ControlMatchBetweenNumberRoomsAndNumberClients(typeOfRoom, numberPossibleFreeRoom, numberPersons, startBooking, endBooking);
                        }
                    }
                    else
                        Console.WriteLine("Mi spiace, non ci sono stanze libere dal {0} al {1}.", startBooking, endBooking);
                }
                else
                    Console.WriteLine("Arrivederci e grazie.");
            }
            else 
            {
                //Inserire prenotazione
                string[] divider = { " " };
                string dataClient = Console.ReadLine();
                string[] data = dataClient.Split(divider, StringSplitOptions.RemoveEmptyEntries);

                Client newClient = _allClients.AddClient(data[0], data[1], data[2]);
                decimal price = _allRooms.GetPriceOfThisRoom(typeOfRoom);
                _allBooking.AddPrenotations(newClient, typeOfRoom, numberPossibleFreeRoom, price, startBooking, endBooking, newClient.Id);
            }

        }
    }
}
